#第十章 序列的修改、散列和切片

from array import array
import reprlib
import math
from functools import reduce
import operator

class Vector:
    typecode = 'd'

    def  __init__(self,components):
        self._components = array(self.typecode,components)
    
    def __iter__(self):
        return iter(self._components)

    def __repr__(self):
        components = reprlib.repr(self._components)
        components = components[components.find('['):-1]
        return "__repr__ Vector({})".format(components)
    
    def __str__(self):
        return  '__str__ '+str(tuple(self))
    def __bytes__(self):
        return (bytes([ord(self.typecode)])+ bytes(self._components)) 

    def __abs__(self):
        return  math.sqrt(sum([x*x for x in self]))

    def __bool__(self):
        return  bool(abs(self))

    def __len__(self): #实现序列接口：计算长度
        return len(self._components)

    def __getitem__(self,index): #实现序列接口：支持切片
        #print(index) #当进行切片时参数 index 是一个slice对象,根据这个特性我们实现切片还是返回的是Vector对象
        cls = type(self)
        if isinstance(index,slice):
            return cls(self._components[index])
        return self._components[index]

    def __getattr__(self,proName): #当访问的属性不存在时会访问该函数
        return 0
    
    def __eq__(self,other): #改进后的eq函数 效率更高
        #return tuple(self) == tuple(other) #这样比较需要复制对象 对于元素太多的对象效率低下
        if len(self) != len(other):
            return False
        else:
            for a,b in zip(self,other):
                if a!=b:
                    return False
        return True
        
    def __hash__(self):
        hashs = list(map(hash,self._components))
        print(hashs)
        return reduce(operator.xor,hashs)

    @classmethod
    def fromBytes(cls,octets):
        typecode = chr(octets[0])
        memv = memoryview(octets[1:]).cast(typecode)
        return cls(memv)
v1 = Vector([x for x in range(0,10)])
print(v1,abs(v1))
print(len(v1),v1[1],v1[1:3],v1.x)
v1.x = 10
print('v1.x',v1.x,"hash",hash(v1))
